#include "resource_mgr.h"
#include "actor.h"

#include <cassert>
#include <fstream>
#include <sstream>

#include <SDL2/SDL_image.h>
#include <SDL2/SDL.h>
#include <nlohmann/json.hpp>

ResourceMgr ResourceMgr::m_instance;

static std::pair<const char *, int> g_gameImageResources[] = {
	{"sflogo", 8}, {"mapbg", 1}, {"map", 12}, {"actor", 4}, {"sptmap", 13}, {"sptprop", 23}, {"sptarm", 10}, {"sptenemy1", 20}, {"ui", 25}, {"xtq", 6}, {"menu", 2}, {"intro", 2}, {"face", 12}, {"sptenemy2", 20}, {"end", 1}, {"load", 2}};

//基础血量
//int monsterHpBaseArray[] = {
//	35, 45, 35,
//	50, 60, 55,
//	100, 50, 260,
//	60, 130, 100,
//	320, 20, 320,
//	100, 210, 220,
//	160, 200,
//	230, 220, 200,
//	360, 180, 180,
//
//	1200, 4500, 1500,
//	8000, 800, 5000,
//	120, 444, 100
//};
////基础攻击力
//int monsterAttackBaseArray[] = {
//	18, 20, 38,
//	42, 32, 52,
//	180, 48, 85,
//	100, 60, 95,
//	120, 100, 140,
//	680, 200, 180,
//	230, 380,
//	450, 370, 390,
//	310, 430, 460,
//
//	180, 560, 600,
//	5000, 500, 1580,
//	150, 199, 65
//};
////基础防御力
//int monsterDefBaseArray[] = {
//	1, 2, 3,
//	6, 8, 12,
//	110, 22, 5,
//	8, 3, 30,
//	15, 68, 20,
//	50, 65, 30,
//	105, 130,
//	100, 110, 90,
//	20, 210, 360,
//
//	20, 310, 250,
//	1000, 100, 190,
//	50, 66, 15
//};

int monsterMoneyArray[] = {
	1, 2, 3,
	6, 5, 8,
	100, 12, 18,
	12, 8, 22,
	30, 28, 30,
	55, 45, 35,
	65, 90,
	100, 80, 50,
	40, 120, 200,

	100, 1000, 800,
	500, 500, 500,
	100, 144, 30};

//std::array< const char*, 88> actorNames = {
//	"孙悟空",		"黄门",		"红门",			"蓝门",			"封印门",	"门卫",			"隐形路径",		"上楼梯",	"下楼梯",	"炼丹炉",
//	"云雾",			"能挖的墙", "隐形墙",		"火眼金睛",		"生死簿",	"筋斗云",		"芭蕉扇",		"金勺子",	"玄明石",	"千年月桂露",
//	"相形变位",		"上行符",	"下行符",		"太公杖",		"捆仙绳",	"幸运币",		"黄钥匙",		"红钥匙",	"蓝钥匙",	"威力丹",
//	"金刚丹",		"回春丸",	"长寿丹",		"桃木棒",		"玄铁棒",	"真银棒",		"金箍棒",		"道袍",		"铁甲",		"锁子甲",
//	"紫金龙鳞甲",	"天宫小犬", "天宫大犬",		"伴炉童子",		"护庭小神", "守园仙婢",		"护庭校尉",		"巡天卫士", "巡天卫士", "巨力士",
//	"执火道人",		"奎木狼",	"执瓶仙侍",		"金刚力士",		"护持迦蓝", "侍案仙女",		"护庭神将",		"赤力韦驮", "护丹老道", "伏魔韦驮",
//	"兜率宫星君",	"无量护法", "兜率宫老仙",	"二郎执旗将",	"杀破狼",	"二郎骁骑将",	"尊天韦驮",		"啸天犬",	"太上老君", "杨戬",
//	"玉皇大帝",		"玉皇大帝", "牛魔王",		"天蓬元帅",		"巨灵神",	"哪吒",			"路点",			"太白金星", "天宫商人", "乌金棍",
//	"银缕锁甲",		"封印门",	"传怪点",		"剧情点",		"嫦娥",		"黄金钥匙",		"日月无极钹",	"菩提老祖"
//};

ResourceMgr &ResourceMgr::get()
{
	return m_instance;
}

bool ResourceMgr::init(SDL_Renderer *pRenderer, const std::filesystem::path &resourcePath, const std::filesystem::path &dataPath)
{
	/*
	{
		{false,"sflogo",8},		{false,"mapbg",1},		{false,"map",12},		{false,"actor",4},		{false,"sptmap",13},
		{false,"sptprop",23},	{false,"sptarm",10},	{false,"sptenemy1",20}, {false,"ui",25},		{false,"xtq",6},
		{false,"menu",2},		{false,"intro",2},		{false,"face",12},		{false,"sptenemy2",20},	{false,"end",1},
		{false,"load",2}
	}
	*/
	//加载资源
	auto resourceJsonPath = dataPath / "resources.json";
	load_resources_config(resourceJsonPath);
	int flags = IMG_INIT_PNG;
	int initted = IMG_Init(flags);
	assert(initted);
	if (!initted)
		return false;
	m_renderer = pRenderer;
	for (auto &data : m_datas)
	{
		data.bloaded = loadResourceImages(pRenderer, resourcePath, data.name, data.size, data.resources);
		assert(data.bloaded);
	}
	//加载actors

	std::vector<int> objectAnimSequenceArray[]{
		{0},
		{0, 1, 0, 2},
		{0, 1, 2},
		{0, 1, 2, 1},
		{0, 1, 2, 2, 1, 0},
		{0, 1, 2, 3, 2, 1},
		{0, 1, 2, 3, 4},
		{3, 4, 5, 6},
		{4, 3, 2, 1, 0},
		{2, 1, 0},
		{2, 3, 4}};

	//每个actor的objectAnimSequenceArray索引
	int spriteUnknownProperty[]{
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 3, 3, 3, 4, 2, 3, 3, 3, 3,
		3, 3, 2, 3, 2, 2, 2, 3, 2, 3,
		3, 3, 2, 3, 5, 3, 3, 3, 3, 3,
		3, 0, 0, 0, 2, 2, 0, 0, 0, 0,
		0, 0, 0, 0, 2, 0, 0, 0, 0};

#ifdef USE_ACTOR_CONFIG
	m_actors = {
		{ActrorType_None, u8"孙悟空", 41, 46, 0, "actor_0"},
		//地面物体
		{ActorType_GroundItem, u8"黄门", 32, 0, 0, "sptmap_0"},
		{ActorType_GroundItem, u8"红门", 32, 0, 0, "sptmap_1"},
		{ActorType_GroundItem, u8"蓝门", 32, 0, 0, "sptmap_2"},
		{ActorType_GroundItem, u8"封印门", 45, 0, 0, "sptmap_3"},
		{ActorType_GroundItem, u8"门卫", 32, 0, 0, "sptmap_4"},
		{ActorType_GroundItem, u8"隐形路径", 32, 0, 0, "sptmap_5"},
		{ActorType_GroundItem, u8"上楼梯", 32, 0, 0, "sptmap_6"},
		{ActorType_GroundItem, u8"下楼梯", 32, 0, 0, "sptmap_7"},
		{ActorType_GroundItem, u8"炼丹炉", 104, 0, 0, "sptmap_8"},
		{ActorType_GroundItem, u8"云雾", 35, 0, 2, "sptmap_9"},
		{ActorType_GroundItem, u8"能挖的墙", 45, 0, 0, "sptmap_10"},
		{ActorType_GroundItem, u8"隐形墙", 30, 0, 0, "sptmap_11"},
		//能力类和消耗品
		{ActorType_PropertyItem, u8"火眼金睛", 32, 0, 0, "sptprop_1", -1, -1, -1, -1},
		{ActorType_PropertyItem, u8"生死簿", 32, 0, 0, "sptprop_2", -1, -1, -1, -1},
		{ActorType_PropertyItem, u8"筋斗云", 30, 0, 0, "sptprop_3", -1, -1, -1, -1},
		{ActorType_PropertyItem, u8"芭蕉扇", 30, 0, 0, "sptprop_4", -1, -1, -1, -1},
		{ActorType_PropertyItem, u8"金勺子", 24, 0, 0, "sptprop_5", -1, -1, -1, 1},
		{ActorType_GroundItem, u8"玄明石", 25, 0, 0, "sptprop_6", -1, -1, -1, 1},
		{ActorType_GroundItem, u8"千年月桂露", 21, 0, 0, "sptprop_7", -1, -1, -1, 1},
		{ActorType_PropertyItem, u8"相形变位", 32, 0, 0, "sptprop_8", -1, -1, -1, 3},
		{ActorType_PropertyItem, u8"上行符", 25, 0, 0, "sptprop_9", -1, -1, -1, 1},
		{ActorType_PropertyItem, u8"下行符", 25, 0, 0, "sptprop_10", -1, -1, -1, 1},
		{ActorType_PropertyItem, u8"太公杖", 27, 0, 0, "sptprop_11", -1, -1, -1, -1},
		{ActorType_PropertyItem, u8"捆仙绳", 31, 0, 0, "sptprop_12", -1, -1, -1, -1},
		{ActorType_PropertyItem, u8"幸运币", 27, 0, 0, "sptprop_13", -1, -1, -1, -1},
		//钥匙，攻防血
		{ActorType_PropertyItem, u8"黄钥匙", 23, 0, 0, "sptprop_14"},
		{ActorType_PropertyItem, u8"红钥匙", 23, 0, 0, "sptprop_15"},
		{ActorType_PropertyItem, u8"蓝钥匙", 23, 0, 0, "sptprop_16"},
		{ActorType_PropertyItem, u8"威力丹", 32, 0, 0, "sptprop_17"},
		{ActorType_PropertyItem, u8"金刚丹", 32, 0, 0, "sptprop_18"},
		{ActorType_PropertyItem, u8"回春丸", 32, 0, 0, "sptprop_19"},
		{ActorType_PropertyItem, u8"长寿丹", 32, 0, 0, "sptprop_20"},
		///////////装备///
		//武器
		{ActorType_Equip, u8"桃木棒", 27, 0, 0, "sptarm_0", 1, 10, -1, -2, u8"\\cdddddd一根相当长的木制长棍,新手必备.有了它杀人越货不慌不愁.\n\\c00ff00装备: 攻击+10.\n\\cFFCC00\"看上去似乎会断掉。\"."},
		{ActorType_Equip, u8"玄铁棒", 27, 0, 0, "sptarm_1", 2, 30, -1, -2, u8"\\cdddddd乌黑油亮，显然经历过多人之手。\n\\c00ff00装备: 攻击+30.\n\\cFFCC00\"很粗很结实！\"."},
		{ActorType_Equip, u8"真银棒", 27, 0, 0, "sptarm_2", 3, 70, -1, -2, u8"\\cdddddd银棍，恩，有这个名字就足够了。\n\\c00ff00装备: 攻击+70.\n\\cFFCC00\"只是根银棍\"."},
		{ActorType_Equip, u8"金箍棒", 27, 0, 0, "sptarm_3", 4, 120, -1, -2, u8"\\cdddddd您的需要，它知道；您的需求，它满足。它好，你也好，龙王后宫，镇宫之宝！\n\\c00ff00装备: 攻击+220.\n\\cFFCC00\"不要迷恋它，它只是一根传说。\"."},
		//防具
		{ActorType_Equip, u8"道袍", 22, 0, 0, "sptarm_4", 1, -1, 10, -3, u8"\\cdddddd没有太多的装饰，一件非常朴素、轻便的布衣.\n\\c00ff00装备: 防御+10.\n\\cFFCC00\"看上去有不少人用过了。\"."},
		{ActorType_Equip, u8"铁甲", 22, 0, 0, "sptarm_5", 2, -1, 30, -3, u8"\\cdddddd保暖御寒，腰不酸，腿不疼，走路也有劲了。\n\\c00ff00装备: 防御+30.\n\\cFFCC00\"豹纹，性感又野性，今年天宫最流行的皮草款式\"."},
		{ActorType_Equip, u8"锁子甲", 16, 0, 0, "sptarm_6", 3, -1, 70, -3, u8"\\cdddddd如果没有上面的那行字，它也算是个杰作。\n\\c00ff00装备: 防御+70.\n\\cFFCC00\"上面写着'办四级神仙证书，回收二手莲花宝座'\"."},
		{ActorType_Equip, u8"紫金龙鳞甲", 25, 0, 0, "sptarm_7", 4, -1, 120, -3, u8"\\cdddddd华丽的装饰，就是有点旧。\n\\c00ff00装备: 防御+120.\n\\cFFCC00\"别人穿过的极品。\"."},
		//怪物
		{ActorType_Monster, u8"天宫小犬", 15, 0, 3, "sptenemy1_0", 35, 18, 1, 1},
		{ActorType_Monster, u8"天宫大犬", 20, 0, 3, "sptenemy1_1", 45, 20, 2, 2},
		{ActorType_Monster, u8"伴炉童子", 28, 0, 3, "sptenemy1_2", 35, 38, 3, 3},
		{ActorType_Monster, u8"护庭小神", 26, 0, 4, "sptenemy1_3", 50, 42, 6, 4},
		{ActorType_Monster, u8"守园仙婢", 23, 0, 2, "sptenemy1_4", 60, 32, 8, 5},
		{ActorType_Monster, u8"护庭校尉", 34, 0, 3, "sptenemy1_5", 55, 52, 12, 8},
		{ActorType_Monster, u8"巡天卫士", 35, 0, 3, "sptenemy1_6", 100, 180, 110, 100},
		{ActorType_Monster, u8"巡天卫士", 24, 0, 3, "sptenemy1_7", 50, 48, 22, 12},
		{ActorType_Monster, u8"巨力士", 33, 0, 3, "sptenemy1_8", 260, 85, 5, 18},
		{ActorType_Monster, u8"执火道人", 22, 0, 3, "sptenemy1_9", 60, 100, 8, 12},
		{ActorType_Monster, u8"奎木狼", 22, 0, 3, "sptenemy1_10", 130, 60, 3, 8},
		{ActorType_Monster, u8"执瓶仙侍", 28, 0, 2, "sptenemy1_11", 100, 95, 30, 22},
		{ActorType_Monster, u8"金刚力士", 36, 0, 3, "sptenemy1_12", 320, 120, 15, 30},
		{ActorType_Monster, u8"护持迦蓝", 38, 0, 2, "sptenemy1_13", 20, 100, 68, 28},
		{ActorType_Monster, u8"侍案仙女", 29, 0, 2, "sptenemy1_14", 320, 140, 20, 30},
		{ActorType_Monster, u8"护庭神将", 34, 0, 2, "sptenemy1_15", 100, 580, 50, 55},
		{ActorType_Monster, u8"赤力韦驮", 29, 0, 3, "sptenemy1_16", 210, 200, 65, 45},
		{ActorType_Monster, u8"护丹老道", 30, 0, 2, "sptenemy1_17", 200, 180, 30, 35},
		{ActorType_Monster, u8"伏魔韦驮", 31, 0, 3, "sptenemy1_18", 160, 230, 105, 65},
		{ActorType_Monster, u8"兜率宫星君", 33, 0, 3, "sptenemy1_19", 200, 380, 130, 90},
		///高级敌人
		{ActorType_Monster, u8"无量护法", 26, 0, 3, "sptenemy2_0", 230, 450, 100, 100},
		{ActorType_Monster, u8"兜率宫老仙", 30, 0, 2, "sptenemy2_1", 220, 370, 110, 80},
		{ActorType_Monster, u8"二郎执旗将", 36, 0, 3, "sptenemy2_2", 200, 390, 90, 50},
		{ActorType_Monster, u8"杀破狼", 23, 0, 5, "sptenemy2_3", 360, 310, 20, 40},
		{ActorType_Monster, u8"二郎骁骑将", 38, 0, 3, "sptenemy2_4", 180, 430, 210, 120},
		{ActorType_Monster, u8"尊天韦驮", 33, 0, 3, "sptenemy2_5", 180, 460, 360, 200},
		{ActorType_Monster, u8"啸天犬", 42, 67, 3, "sptenemy2_6", 1200, 180, 20, 100},
		{ActorType_Monster, u8"太上老君", 32, 0, 3, "sptenemy2_7", 4500, 560, 310, 1000},
		{ActorType_Monster, u8"杨戬", 96, 32, 3, "sptenemy2_8", 1500, 600, 250, 800},
		{ActorType_Monster, u8"玉皇大帝", 38, 0, 3, "sptenemy2_9", 8000, 5000, 1000, 500},
		{ActorType_Monster, u8"玉皇大帝", 36, 0, 0, "sptenemy2_10", 800, 500, 100, 500},
		{ActorType_NPC, u8"牛魔王", 32, 45, 0, "sptenemy2_11", 5000, 1580, 190, 500},
		{ActorType_Monster, u8"天蓬元帅", 39, 0, 0, "sptenemy2_12", 120, 150, 50, 100},
		{ActorType_Monster, u8"巨灵神", 59, 0, 2, "sptenemy2_13", 444, 199, 66, 144},
		{ActorType_Monster, u8"哪吒", 36, 0, 2, "sptenemy2_14", 100, 65, 15, 30},
		//地面物体
		{ActorType_GroundItem, u8"路点", 32, 0, 0, "sptenemy2_15"},
		//商人
		{ActorType_BusinessMan, u8"太白金星", 29, 0, 0, "sptenemy2_16"},
		{ActorType_BusinessMan, u8"天宫商人", 37, 0, 0, "sptenemy2_17"},
		//装备
		{ActorType_Equip, u8"乌金棍", 27, 0, 0, "sptarm_8", 5, 220, -1, -2, u8"\\cdddddd您的需要，它知道；您的需求，它满足。它好，你也好，龙王后宫，镇宫之宝！\n\\c00ff00装备: 攻击+220.\n\\cFFCC00\"不要迷恋它，它只是一根传说。\"."},
		{ActorType_Equip, u8"银缕锁甲", 17, 0, 0, "sptarm_9", 5, -1, 220, -3, u8"\\cdddddd东海龙鳞编织而成，限量版，天上天下，只此一款。\n\\c00ff00装备: 防御+220.\n\\cFFCC00\"更轻薄，更透气，更多防护，更多安心\"."},
		//零散的地面物品
		{ActorType_GroundItem, u8"封印门", 32, 0, 0, "sptmap_3"},
		{ActorType_GroundItem, u8"传怪点", 32, 0, 0, "sptmap_4"},
		{ActorType_GroundItem, u8"剧情点", 32, 0, 0, ""},
		//NPC
		{ActorType_NPC, u8"嫦娥", 29, 0, 2, "sptenemy2_18"},
		//属性物品
		{ActorType_PropertyItem, u8"黄金钥匙", 27, 0, 0, "sptprop_21", -1, -1, -1, 1},
		{ActorType_PropertyItem, u8"日月无极钹", 32, 0, 0, "sptprop_22" - 1, -1, -1, 1},
		//NPC
		{ActorType_NPC, u8"菩提老祖", 36, 0, 0, "sptenemy2_19"}};

#ifdef _DEBUG
	m_actors[12].resourceName = m_actors[11].resourceName; //隐藏墙替换为正式墙
	m_actors[71].resourceName = m_actors[70].resourceName; //第二个玉皇大帝换为正常贴图
#endif
#else
	//读取actors
	auto actorJsonPath = dataPath / "actors.json";
	load_actors_config(actorJsonPath);
#endif
	return true;
}

bool ResourceMgr::loadResourceImages(SDL_Renderer *pRenderer, const std::filesystem::path &basePath, const std::string &filename, int count, std::vector<std::shared_ptr<GLTexture>> &imageDatas)
{
	try
	{
		std::filesystem::path path = basePath / filename;
		std::ifstream fs;
		fs.open(path, std::ios::binary);
		if (fs.fail())
		{
			return false;
		}
		//循环转存
		for (int i = 0; i < count; i++)
		{
			int size = readBinaryShort(fs);
			if (!size)
			{
				//std::cout << "get size failed !" << std::endl;
				SDL_LogError(SDL_LOG_CATEGORY_ERROR, "get size failed!");
				return false;
			}
			auto data = std::shared_ptr<char[]>(new char[size]());
			fs.read(data.get(), size);

			SDL_RWops *rwOps = SDL_RWFromConstMem(data.get(), size);
			SDL_Texture *texture = IMG_LoadTexture_RW(pRenderer, rwOps, SDL_TRUE);
			if (texture)
			{
				int w, h;
				SDL_QueryTexture(texture, nullptr, nullptr, &w, &h);
				auto pTexture = std::make_shared<GLTexture>(w, h, texture);
				imageDatas.push_back(pTexture);
			}
		}
	}
	catch (const std::exception &e)
	{
		//std::cout << "error: " << e.what() << std::endl;
		SDL_LogError(SDL_LOG_CATEGORY_ERROR, "error: %s", e.what());
	}
	return true;
}

ActorInfo &ResourceMgr::getActor(int index)
{
	return m_actors[index];
}

ResourceData &ResourceMgr::operator[](int index)
{
	assert(index > 0 && index < m_datas.size());
	return m_datas[index];
}

ResourceData &ResourceMgr::operator[](const std::string &name)
{
	auto pos = std::find_if(m_datas.begin(), m_datas.end(), [&name](const ResourceData &data)
							{ return name == data.name; });
	assert(pos != m_datas.end());
	return *pos;
}

short ResourceMgr::readBinaryShort(std::ifstream &fs)
{
	short size = fs.get() & 0xFF | fs.get() << 8 & 0xFF00;
	return size;
}

bool ResourceMgr::load_resources_config(const std::filesystem::path &config_file_path)
{
	//读取配置文件
	std::ifstream ifs;
	ifs.open(config_file_path);
	if (ifs.fail())
	{
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "open config file failed !");
		return false;
	}
	std::string strJson;
	std::stringstream ss(strJson);
	ss << ifs.rdbuf();
	auto j = nlohmann::json::parse(ss.str());
	if (!j.is_array())
		return false;
	for (size_t i = 0; i < j.size(); i++)
	{
		const auto &childObj = j[i];
		if (childObj.empty())
			continue;
		std::string name;
		int count;
		if (!childObj.contains("name") || !childObj.contains("count"))
			continue;
		childObj.at("name").get_to(name);
		childObj.at("count").get_to(count);
		m_datas.push_back({false, name, count});
	}
	return true;
}

bool ResourceMgr::load_actors_config(const std::filesystem::path &config_file_path)
{
	//读取配置文件
	std::ifstream ifs;
	ifs.open(config_file_path);
	if (ifs.fail())
	{
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "open config file failed !");
		return false;
	}
	std::string strJson;
	std::stringstream ss(strJson);
	ss << ifs.rdbuf();
	auto j = nlohmann::json::parse(ss.str());
	if (!j.is_array())
		return false;
	for (size_t i = 0; i < j.size(); i++)
	{
		const auto &actor_obj = j[i];
		if (actor_obj.empty())
			continue;
		actor_type type;
		std::string name;
		int count;
		if (!actor_obj.contains("type") || !actor_obj.contains("name") || !actor_obj.contains("sprite"))
			continue;
		actor_obj.at("type").get_to(type);
		actor_obj.at("name").get_to(name);
		const auto &sprite_obj = actor_obj.at("sprite");
		int width = 0, height = 0;
		std::string resourceName;
		std::vector<int> anims;
		if (sprite_obj.contains("width"))
			sprite_obj.at("width").get_to(width);
		if (sprite_obj.contains("height"))
			sprite_obj.at("height").get_to(height);
		if (sprite_obj.contains("resourceName"))
			sprite_obj.at("resourceName").get_to(resourceName);
		if (sprite_obj.contains("animSequence"))
		{
			auto animArray = sprite_obj["animSequence"];
			if (animArray.is_array())
			{
				auto arr = animArray.array();
				for (int i = 0; i < arr.array().size(); i++)
				{
					if (!arr[i].is_number_integer())
						continue;
					int v;
					arr[i].get_to(v);
					anims.push_back(v);
				}
			}
		}

		std::shared_ptr<actor> pActor;
		switch (type)
		{
		case actor_type::player:
		{
			auto obj = std::make_shared<PlayerActor>();
			pActor = std::dynamic_pointer_cast<actor>(obj);
		}
		break;
		case actor_type::ground_item:
		{
			auto obj = std::make_shared<tileActor>();
			pActor = std::dynamic_pointer_cast<actor>(obj);
		}
		break;
		case actor_type::property_item:
		{
			auto obj = std::make_shared<itemActor>();
			pActor = std::dynamic_pointer_cast<actor>(obj);
		}
		break;
		case actor_type::equipment:
		{
			auto obj = std::make_shared<equipmentActor>();
			pActor = std::dynamic_pointer_cast<actor>(obj);
		}
		break;
		case actor_type::monster:
		{
			auto obj = std::make_shared<enemyActor>();
			pActor = std::dynamic_pointer_cast<actor>(obj);
		}
		break;
		case actor_type::business_man:
		{
			auto obj = std::make_shared<shopNpcActor>();
			pActor = std::dynamic_pointer_cast<actor>(obj);
		}
		break;
		case actor_type::npc:
		{
			auto obj = std::make_shared<npcActor>();
			pActor = std::dynamic_pointer_cast<actor>(obj);
		}
		break;
		default:
			break;
		}
		if (pActor)
		{
			pActor->_resourceName = resourceName;
			pActor->_name = name;
			pActor->_width = width;
			pActor->_height = height;
			pActor->_animations = anims;
			//add object
			m_actorObjs.push_back(pActor);
		}
	}
	return true;
}

/////////////////////////////////////////////////////////////////////////////
//ActorInfo
/////////////////////////////////////////////////////////////////////////////
std::vector<std::vector<int>> ActorInfo::objectAnimSequenceArray = {
	{0},
	{0, 1, 0, 2},
	{0, 1, 2},
	{0, 1, 2, 1},
	{0, 1, 2, 2, 1, 0},
	{0, 1, 2, 3, 2, 1},
	{0, 1, 2, 3, 4},
	{3, 4, 5, 6},
	{4, 3, 2, 1, 0},
	{2, 1, 0},
	{2, 3, 4}};

std::shared_ptr<GLTexture> ActorInfo::getRenderResource()
{
	auto strResourceName = std::string(resourceName);
	if (strResourceName.empty()) //没有图
		return nullptr;
	auto pos = strResourceName.find_first_of("_");
	if (pos == std::string::npos)
		return nullptr;
	auto name = strResourceName.substr(0, pos);
	auto number = strResourceName.substr(pos + 1);
	int iNumber = atoi(number.data());
	return ResourceMgr::get()[name][iNumber];
}

int ActorInfo::getAnimFrameSize()
{
	if (animSequenceIndex < 0 || animSequenceIndex > objectAnimSequenceArray.size())
		return objectAnimSequenceArray[0].size();
	return objectAnimSequenceArray[animSequenceIndex].size();
}

int ActorInfo::getAnimIndex()
{
	if (animSequenceIndex < 0 || animSequenceIndex > objectAnimSequenceArray.size())
		return 0;
	if (currFrameIdx < 0 || currFrameIdx > objectAnimSequenceArray[animSequenceIndex].size())
		return 0;
	return objectAnimSequenceArray[animSequenceIndex][currFrameIdx];
}
